//------------------------------------------------------------------------------
//------Created by RadioOperator 2020-07-17-------------------------------------
//------------------------------------------------------------------------------

#include <stdint.h>
#include <stdio.h>
#include <string.h>

//RAM Drive
uint32_t RamDrive[192*1024/4] __attribute__((section("RAM_Drive"))); //RAM Disk size
uint32_t ram_disk_base = (uint32_t) &RamDrive; //take the RAM Disk base address

//RAM Disk FAT Image, Boot Sector
//0-2	  0xEB,0x3C,0x90, Assembly code instructions to jump to boot code (mandatory in bootable partition)
//3-10	"MSDOS5.0"      OEM name in ASCII
//11-12	0x0200=512,     Bytes per sector (512, 1024, 2048, or 4096)
//13	  1,              Sectors per cluster (Must be a power of 2 and cluster size must be <=32 KB)
//14-15	0x0400=1024,    Size of reserved area, in sectors
//16	  2,              Number of FATs (usually 2)
//17-18	0x0200=512,     Maximum number of files in the root directory (FAT12/16; 0 for FAT32)
//19-20	0x0180=384,     Number of sectors in the file system; if 2 B is not large enough, set to 0 and use 4 B value in bytes 32-35 below
//                      384x512=192KB
//21	  0xF8,           Media type (0xf0=removable disk, 0xf8=fixed disk)
//22-23	0x0002=2,       Size of each FAT, in sectors, for FAT12/16; 0 for FAT32
//24-25	0x0001=1,       Sectors per track in storage device
//26-27	0x0001=1,       Number of heads in storage device
//28-31	0,              Number of sectors before the start partition
//32-35	0,              Number of sectors in the file system; this field will be 0 if the 2B field above (bytes 19-20) is non-zero
//36	  0x80            BIOS INT 13h (low level disk services) drive number
//37	  0x00            Not used
//38	  0x29            Extended boot signature to validate next three fields (0x29)
//39-42	0x9E1A4429      Volume serial number
//43-53	"NO NAME    "   Volume label, in ASCII
//54-61	"FAT12   "      File system type level, in ASCII. (Generally "FAT", "FAT12", or "FAT16")
//62-509	Not used
//510-511	0xAA55        Signature value (0xaa55)
const unsigned char RamAddress0000[] = {
  0xEB,0x3C,0x90, 'M', 'S', 'D', 'O', 'S', '5', '.', '0',0x00,0x02,0x01,0x04,0x00,
  0x02,0x00,0x02,0x80,0x01,0xF8,0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x80,0x00,0x29,0x6E,0x22,0x06,0x66, 'N', 'O', ' ', 'N', 'A',
   'M', 'E', ' ', ' ', ' ', ' ', 'F', 'A', 'T', '1', '2', ' ', ' ', ' ',0x33,0xC9,
  0x8E,0xD1,0xBC,0xF0,0x7B,0x8E,0xD9,0xB8,0x00,0x20,0x8E,0xC0,0xFC,0xBD,0x00,0x7C,
  0x38,0x4E,0x24,0x7D,0x24,0x8B,0xC1,0x99,0xE8,0x3C,0x01,0x72,0x1C,0x83,0xEB,0x3A,
  0x66,0xA1,0x1C,0x7C,0x26,0x66,0x3B,0x07,0x26,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA,
  0x02,0x88,0x56,0x02,0x80,0xC3,0x10,0x73,0xEB,0x33,0xC9,0x8A,0x46,0x10,0x98,0xF7,
  0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E,0x13,0xD1,0x8B,0x76,0x11,
  0x60,0x89,0x46,0xFC,0x89,0x56,0xFE,0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03,
  0xC3,0x48,0xF7,0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x00,0xE8,0xE6,
  0x00,0x72,0x39,0x26,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE,0xA1,0x7D,0xF3,0xA6,
  0x61,0x74,0x32,0x4E,0x74,0x09,0x83,0xC7,0x20,0x3B,0xFB,0x72,0xE6,0xEB,0xDC,0xA0,
  0xFB,0x7D,0xB4,0x7D,0x8B,0xF0,0xAC,0x98,0x40,0x74,0x0C,0x48,0x74,0x13,0xB4,0x0E,
  0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEF,0xA0,0xFD,0x7D,0xEB,0xE6,0xA0,0xFC,0x7D,0xEB,
  0xE1,0xCD,0x16,0xCD,0x19,0x26,0x8B,0x55,0x1A,0x52,0xB0,0x01,0xBB,0x00,0x00,0xE8,
  0x3B,0x00,0x72,0xE8,0x5B,0x8A,0x56,0x24,0xBE,0x0B,0x7C,0x8B,0xFC,0xC7,0x46,0xF0,
  0x3D,0x7D,0xC7,0x46,0xF4,0x29,0x7D,0x8C,0xD9,0x89,0x4E,0xF2,0x89,0x4E,0xF6,0xC6,
  0x06,0x96,0x7D,0xCB,0xEA,0x03,0x00,0x00,0x20,0x0F,0xB6,0xC8,0x66,0x8B,0x46,0xF8,
  0x66,0x03,0x46,0x1C,0x66,0x8B,0xD0,0x66,0xC1,0xEA,0x10,0xEB,0x5E,0x0F,0xB6,0xC8,
  0x4A,0x4A,0x8A,0x46,0x0D,0x32,0xE4,0xF7,0xE2,0x03,0x46,0xFC,0x13,0x56,0xFE,0xEB,
  0x4A,0x52,0x50,0x06,0x53,0x6A,0x01,0x6A,0x10,0x91,0x8B,0x46,0x18,0x96,0x92,0x33,
  0xD2,0xF7,0xF6,0x91,0xF7,0xF6,0x42,0x87,0xCA,0xF7,0x76,0x1A,0x8A,0xF2,0x8A,0xE8,
  0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01,0x02,0x80,0x7E,0x02,0x0E,0x75,0x04,0xB4,0x42,
  0x8B,0xF4,0x8A,0x56,0x24,0xCD,0x13,0x61,0x61,0x72,0x0B,0x40,0x75,0x01,0x42,0x03,
  0x5E,0x0B,0x49,0x75,0x06,0xF8,0xC3,0x41,0xBB,0x00,0x00,0x60,0x66,0x6A,0x00,0xEB,
  0xB0,0x42,0x4F,0x4F,0x54,0x4D,0x47,0x52,0x20,0x20,0x20,0x20,0x0D,0x0A,0x52,0x65,
  0x6D,0x6F,0x76,0x65,0x20,0x64,0x69,0x73,0x6B,0x73,0x20,0x6F,0x72,0x20,0x6F,0x74,
  0x68,0x65,0x72,0x20,0x6D,0x65,0x64,0x69,0x61,0x2E,0xFF,0x0D,0x0A,0x44,0x69,0x73,
  0x6B,0x20,0x65,0x72,0x72,0x6F,0x72,0xFF,0x0D,0x0A,0x50,0x72,0x65,0x73,0x73,0x20,
  0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x72,0x65,0x73,0x74,0x61,
  0x72,0x74,0x0D,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xCB,0xD8,0x55,0xAA
};

const unsigned char RamAddress0800[] = {
  0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F
};

const unsigned char RamAddress0C00[] = {
  0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F
};

//root file directory field here
const unsigned char RamAddress1000[] = { //Volume Name = APP_HERE
   'A', 'P', 'P', '_', 'H', 'E', 'R', 'E', ' ', ' ', ' ',0x08,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0xB6,0x78,0xED,0x50,0x00,0x00,0x00,0x00,0x00,0x00,
  0x42,0x20,0x00,0x49,0x00,0x6E,0x00,0x66,0x00,0x6F,0x00,0x0F,0x00,0x72,0x72,0x00,
  0x6D,0x00,0x61,0x00,0x74,0x00,0x69,0x00,0x6F,0x00,0x00,0x00,0x6E,0x00,0x00,0x00,
  0x01,0x53,0x00,0x79,0x00,0x73,0x00,0x74,0x00,0x65,0x00,0x0F,0x00,0x72,0x6D,0x00,
  0x20,0x00,0x56,0x00,0x6F,0x00,0x6C,0x00,0x75,0x00,0x00,0x00,0x6D,0x00,0x65,0x00,
  0x53,0x59,0x53,0x54,0x45,0x4D,0x7E,0x31,0x20,0x20,0x20,0x16,0x00,0x89,0xB5,0x78,
  0xED,0x50,0xED,0x50,0x00,0x00,0xB6,0x78,0xED,0x50,0x02,0x00,0x00,0x00,0x00,0x00
};

const unsigned char RamAddress5000[] = {
  0x2E,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x00,0x89,0xB5,0x78,
  0xED,0x50,0xED,0x50,0x00,0x00,0xB6,0x78,0xED,0x50,0x02,0x00,0x00,0x00,0x00,0x00,
  0x2E,0x2E,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x00,0x89,0xB5,0x78,
  0xED,0x50,0xED,0x50,0x00,0x00,0xB6,0x78,0xED,0x50,0x00,0x00,0x00,0x00,0x00,0x00,
  0x42,0x74,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0xCE,0xFF,0xFF,
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
  0x01,0x57,0x00,0x50,0x00,0x53,0x00,0x65,0x00,0x74,0x00,0x0F,0x00,0xCE,0x74,0x00,
  0x69,0x00,0x6E,0x00,0x67,0x00,0x73,0x00,0x2E,0x00,0x00,0x00,0x64,0x00,0x61,0x00,
  0x57,0x50,0x53,0x45,0x54,0x54,0x7E,0x31,0x44,0x41,0x54,0x20,0x00,0x89,0xB5,0x78,
  0xED,0x50,0xED,0x50,0x00,0x00,0xB6,0x78,0xED,0x50,0x03,0x00,0x0C,0x00,0x00,0x00,
  0x42,0x47,0x00,0x75,0x00,0x69,0x00,0x64,0x00,0x00,0x00,0x0F,0x00,0xFF,0xFF,0xFF,
  0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
  0x01,0x49,0x00,0x6E,0x00,0x64,0x00,0x65,0x00,0x78,0x00,0x0F,0x00,0xFF,0x65,0x00,
  0x72,0x00,0x56,0x00,0x6F,0x00,0x6C,0x00,0x75,0x00,0x00,0x00,0x6D,0x00,0x65,0x00,
  0x49,0x4E,0x44,0x45,0x58,0x45,0x7E,0x31,0x20,0x20,0x20,0x20,0x00,0xA7,0xB7,0x78,
  0xED,0x50,0xED,0x50,0x00,0x00,0xB8,0x78,0xED,0x50,0x04,0x00,0x4C,0x00,0x00,0x00
};

const unsigned char RamAddress5200[] = {
  0x0C,0x00,0x00,0x00,0x12,0x54,0xF8,0x24,0xF0,0x27,0x48,0x03,0x00,0x00,0x00,0x00
};

const unsigned char RamAddress5400[] = {
  0x7B,0x00,0x36,0x00,0x42,0x00,0x41,0x00,0x44,0x00,0x32,0x00,0x41,0x00,0x36,0x00,
  0x44,0x00,0x2D,0x00,0x36,0x00,0x41,0x00,0x31,0x00,0x39,0x00,0x2D,0x00,0x34,0x00,
  0x35,0x00,0x44,0x00,0x39,0x00,0x2D,0x00,0x41,0x00,0x43,0x00,0x37,0x00,0x42,0x00,
  0x2D,0x00,0x44,0x00,0x30,0x00,0x32,0x00,0x46,0x00,0x35,0x00,0x34,0x00,0x38,0x00,
  0x36,0x00,0x36,0x00,0x46,0x00,0x30,0x00,0x36,0x00,0x7D,0x00,0x00,0x00,0x00,0x00
};


static void vWriteRAM(uint32_t *StartAddress, const unsigned char *data, uint32_t len)
{
  memcpy(StartAddress, data, len);
}

//format RAM disk
void MSCformat(void)
{
  uint32_t *addr1;
  
  //RAM address: 0x0000 - 0x0800
  addr1 = (uint32_t *) (ram_disk_base);
  vWriteRAM(addr1, RamAddress0000, sizeof(RamAddress0000));
  //RAM address: 0x0800 - 0x0C00
  addr1 = (uint32_t *) (ram_disk_base+0x00000800);
  vWriteRAM(addr1, RamAddress0800, sizeof(RamAddress0800));
  //RAM address: 0x0C00 - 0x1000
  addr1 = (uint32_t *) (ram_disk_base+0x00000C00);
  vWriteRAM(addr1, RamAddress0C00, sizeof(RamAddress0C00));
  //RAM address: 0x1000 - 0x5000
  addr1 = (uint32_t *) (ram_disk_base+0x00001000);
  vWriteRAM(addr1, RamAddress1000, sizeof(RamAddress1000));
  //RAM address: 0x5000 - 0x5200
  addr1 = (uint32_t *) (ram_disk_base+0x00005000);
  vWriteRAM(addr1, RamAddress5000, sizeof(RamAddress5000));
  //RAM address: 0x5200 - 0x5400
  addr1 = (uint32_t *) (ram_disk_base+0x00005200);
  vWriteRAM(addr1, RamAddress5200, sizeof(RamAddress5200));
  //RAM address: 0x5400 - 0x5600
  addr1 = (uint32_t *) (ram_disk_base+0x00005400);
  vWriteRAM(addr1, RamAddress5400, sizeof(RamAddress5400));
}

